package py.edu.ucom.poo.waterloo.agente;

import java.util.Random;


import py.edu.ucom.poo.waterloo.Ficha;
import py.edu.ucom.poo.waterloo.Movimiento;
import py.edu.ucom.poo.waterloo.SandBox;
import py.edu.ucom.poo.waterloo.Tablero;
import py.edu.ucom.poo.waterloo.WaterlooApplicationException;
import py.edu.ucom.poo.waterloo.WaterlooLogicException;

/**
 *
 * @author waterlooTeam
 * @version 1.0 Beta
 */
public class AgenteTest extends Agente
{


    public Tablero ubicarFichas(Ficha[] f, Tablero t)
    {
        this.setFicha(f);
        this.color = f[0].getColor();
        setMapaInterno(armarTableroInicial(t, f, 5));
        return mapaInterno;
    }

    public Movimiento jugar()
    {
    	try{
        Estado eIni = new Estado();
        eIni.setT(mapaInterno);
        this.generarTableros(eIni, 0, 1);
        Estado estado = eIni.getHijoConMayorPeso();
        this.setTableroFicha(estado.getM());
        return estado.getM();
    	}catch(Throwable e){
    		e.printStackTrace();
    		return null;
    	}
    }

    public boolean generarTableros(Estado estado, int nivelProfunidadActual, int nivelProfunidadMaximo){
    	for (int i = 0; i < 10; i++){
            for (int j = 0; j < 10; j++){
                if (this.getSandBoxInterface().hayFicha(i, j) == true && this.color == estado.getT().getCasillaDelTablero(i, j).getFicha().getColor()){
                    moverColumna(estado, i, j, POSITIVO, nivelProfunidadActual, nivelProfunidadMaximo);
                }
            }
        }
        for (int i = 0; i < 10; i++){
            for (int j = 0; j < 10; j++){
                if (this.getSandBoxInterface().hayFicha(i, j) == true && this.color == estado.getT().getCasillaDelTablero(i, j).getFicha().getColor()){
                    moverColumna(estado, i, j, NEGATIVO, nivelProfunidadActual, nivelProfunidadMaximo);
                }
            }
        }
        for (int i = 0; i < 10; i++){
            for (int j = 0; j < 10; j++){
                if (this.getSandBoxInterface().hayFicha(i, j) == true && this.color == estado.getT().getCasillaDelTablero(i, j).getFicha().getColor())
                {
                    moverFila(estado, i, j, POSITIVO, nivelProfunidadActual, nivelProfunidadMaximo);
                }
            }
        }
        for (int i = 0; i < 10; i++){
            for (int j = 0; j < 10; j++){
                if (this.getSandBoxInterface().hayFicha(i, j) == true && this.color == estado.getT().getCasillaDelTablero(i, j).getFicha().getColor()){
                    moverFila(estado, i, j, NEGATIVO, nivelProfunidadActual, nivelProfunidadMaximo);
                }
            }
        }
        return true;
    }


    void moverColumna(Estado estadoAnterior, int i, int j, int incremento, int nivelProfundidadActual, int nivelProfunidadMaximo)
    {
        if (i + incremento < 10 && i + incremento >= 0)
        {
            nivelProfundidadActual++;
            Estado estadoNuevo = new Estado();
            estadoNuevo.getM().setOrigen(estadoAnterior.getT().getCasillaDelTablero(i, j));
            estadoNuevo.getM().setDestino(estadoAnterior.getT().getCasillaDelTablero(i + incremento, j));
            try
            {
                Tablero nuevoTablero = sandBoxInterface.getTablero(estadoAnterior.getT(), estadoNuevo.getM());
                if (incremento==POSITIVO && this.getColor()==SandBox.COLOR_BLUE){
                	estadoNuevo.setPeso(5);
    			}
                if (incremento==NEGATIVO && this.getColor()==SandBox.COLOR_RED){
                	estadoNuevo.setPeso(5);
                }
                //this.imprimirTablero(estadoAnterior.getT());
                estadoNuevo.setT(nuevoTablero);
                this.generarDatos(estadoNuevo);
                estadoAnterior.agregarHijo(estadoNuevo);
                estadoNuevo.setAnterior(estadoAnterior);
                if (nivelProfundidadActual < nivelProfunidadMaximo)
                {
                    generarTableros(estadoNuevo, nivelProfundidadActual, nivelProfunidadMaximo);
                }
                else
                {
                    asignarPeso(estadoNuevo,this);
                }
            } catch (WaterlooLogicException e)
            {
            //no se hace nada porque significa que el tablero no es valido y se descarta la rama
            }
        }
    }

    void moverFila(Estado estadoAnterior, int i, int j, int incremento, int nivelProfundidadActual, int nivelProfunidadMaximo)
    {
        if (j + incremento < 10 && j + incremento >= 0)
        {
            nivelProfundidadActual++;
            Estado estadoNuevo = new Estado();
            estadoNuevo.getM().setOrigen(estadoAnterior.getT().getCasillaDelTablero(i, j));
            estadoNuevo.getM().setDestino(estadoAnterior.getT().getCasillaDelTablero(i, j + incremento));
            try
            {
                Tablero nuevoTablero = sandBoxInterface.getTablero(estadoAnterior.getT(), estadoNuevo.getM());
                estadoNuevo.setT(nuevoTablero);
                this.generarDatos(estadoNuevo);
                estadoAnterior.agregarHijo(estadoNuevo);
                estadoNuevo.setAnterior(estadoAnterior);
                if (nivelProfundidadActual < nivelProfunidadMaximo)
                {
                    generarTableros(estadoNuevo, nivelProfundidadActual, nivelProfunidadMaximo);
                }
                else
                {
                    asignarPeso(estadoNuevo,this);
                }
            } catch (WaterlooLogicException e)
            {
            //no se hace nada porque significa que el tablero no es valido y se descarta la rama
            }
        }
    }


    public void asignarPeso(Estado e,Agente a)
    {
        int piezasPadre = e.getPiezasAntes();
        int piezasHijo = e.getPiezas();
        if (piezasHijo < piezasPadre){
            e.setPeso(2);
        }
        if (piezasHijo == piezasPadre){
            e.setPeso(1);
        }
        if (piezasHijo > piezasPadre){
            e.setPeso(1);
        }
        if (this.sandBoxInterface.hayFicha(e.getM().getDestino().getPosX(),e.getM().getDestino().getPosX())== true)
        	e.setPeso(2);
        
        Ficha f=e.getM().getOrigen().getFicha();
        if (f!=null){
     	   e.setPeso(-5*(f.getVisitaAgente(e.getM().getOrigen().getPosX(),e.getM().getOrigen().getPosY())));
        }
        try {
			if(a.sandBoxInterface.getValor(e.getM().getOrigen().getFicha(), a)>0){
				e.setPeso(2);
			}
		} catch (WaterlooLogicException e1) {
			//e1.printStackTrace();
		} catch (WaterlooApplicationException e1) {
			//e1.printStackTrace();
		}
    }

    public void generarDatos(Estado estadoNuevo)
    {
        int countCantidadFichasAntes = 0;
        for (int i = 0; i < 10; i++){
            for (int j = 0; j < 10; j++){
                if (mapaInterno.getCasillaDelTablero(i, j).getFicha().getColor() == this.getColor()){
                    countCantidadFichasAntes++;
                }
            }
        }
        estadoNuevo.setPiezasAntes(countCantidadFichasAntes);
        int countCantidadDeFichasDespues = 0;
        for (int i = 0; i < 10; i++){
            for (int j = 0; j < 10; j++){
                if (estadoNuevo.getT().getCasillaDelTablero(i, j).getFicha().getColor() == this.getColor()){
                    countCantidadDeFichasDespues++;
                }
            }
        }
        estadoNuevo.setPiezas(countCantidadDeFichasDespues);
    }

    
    public void setTableroFicha(Movimiento m){
    	m.getOrigen().getFicha().setVisitaAgente(m.getOrigen().getPosX(), m.getOrigen().getPosY());
    }
    
    /**
     * Metodo para cargar las fichas para el inicio del juego
     * @param ficha
     * Array de fichas que pasa el SandBox al agente
     * @param j
     * Tipo de jugada
     * 1 = Todas las fichas en forma aleatorias
     * 2 = Forma ordenada. Se debe cargar el vector "orden" con los valores de
     * las fichas. Empieza por la ficha del angulo inferior derecho del tablero del
     * jugador. Una vez que llega al extremo sube 1 fila, se empieza a cargar desde
     * la primera casilla de la derecha hasta el siguiente extremo. Estos pasos se
     * repite sucesibamente hasta cargar las 40 fichas del jugador
     * @return
     * Retorna el array de fichas con las posiciones para cargar en el tablero
     * en forma secuancial
     */
    protected Tablero armarTableroInicial (Tablero t, Ficha[] ficha, int j)
    {
        Ficha[] fichaAuxiliar = new Ficha[40];
        fichaAuxiliar = duplicarFicha(ficha);
        Random r = new Random();
        int z = 0, f, fFin, c=0;
        if (fichaAuxiliar[0].getColor() == SandBox.COLOR_RED) {
            f = 6;
            fFin = 9;
        }
        else {
            f = 0;
            fFin = 3;
        }
        if (j == 1) {///aleatorio
            for (int i = f; i <= fFin; i++) {
                for (c = 0; c < 10; c++) {
                    do {
                        z = r.nextInt(40);
                    } while (fichaAuxiliar[z] == null);
                    if (t.getCasillaDelTablero(i, c).getFicha().getValor() == -1) {
                        t.setFichaEnTablero(i, c, fichaAuxiliar[z]);
                        fichaAuxiliar[z] = null;
                    }

                }

            }
        }
        else if (j == 2) {

            //Cargar Manualmente este vector con los valores de las
            //fichas para que ordene y luego retorne para su cargado
            //en el tablero
            int[] orden = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12};
            z = 0;
            for (int i = f; i <= fFin; i++) {

                for (int x = 0; x < 10; x++) {

                    t.setFichaEnTablero(i, x, ficha[z]);
                    ficha[z] = null;
                    z++;
                }
            }
        }
        else if (j == 3) {
        	//randomico entre 7 y 9 
            int a = 0, band = 0, posFila=0;
            posFila = f + (r.nextInt(2) + 1);
            c = r.nextInt(8) + 1;
            do {
                if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 1 && band == 0) {
                    t.setFichaEnTablero(posFila, c, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 1;
                }
                else if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 8 && band == 1) {
                    t.setFichaEnTablero(posFila + 1, c + 1, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 2;
                }
                else if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 9 && band == 2) {
                    t.setFichaEnTablero(posFila - 1, c - 1, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 3;
                }
                else if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 11 && band == 3) {
                    t.setFichaEnTablero(posFila, c + 1, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 4;
                }
                else if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 11 && band == 4) {
                    t.setFichaEnTablero(posFila, c - 1, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 5;
                }
                else if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 11 && band == 5) {
                    t.setFichaEnTablero(posFila + 1, c, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 6;
                }
                else if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 11 && band == 6) {
                    t.setFichaEnTablero(posFila - 1, c, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 7;
                    break;
                }
                a++;

            } while (null == null);
            for (int i = f; i <= fFin; i++) {
                for (c = 0; c < 10; c++) {
                    if (t.getCasillaDelTablero(i, c).getFicha().getValor() == -1) {
                        do {
                            z = r.nextInt(40);
                        } while (fichaAuxiliar[z] == null);
                        if (t.getCasillaDelTablero(i, c).getFicha().getValor() == -1) {
                            t.setFichaEnTablero(i, c, fichaAuxiliar[z]);
                            fichaAuxiliar[z] = null;
                        }

                    }
                } // End for

            } // End for

        } // End if
        else if (j == 4) {
        	//7 y 8 pero solo en soreccion de puentes
            int a = 0, band = 0, posFila = 0;
            int colAleatoria = r.nextInt(3);
            if (colAleatoria == 0){
                c = 1;
            }else if (colAleatoria == 1){
                c = 5;
            }else if (colAleatoria == 2){
                c = 8;
            }
            posFila = f + (r.nextInt(2) + 1);
            do {
                if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 1 && band == 0) {
                    t.setFichaEnTablero(posFila, c, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 1;
                }
                else if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 8 && band == 1) {
                    t.setFichaEnTablero(posFila + 1, c + 1, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 2;
                }
                else if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 9 && band == 2) {
                    t.setFichaEnTablero(posFila - 1, c - 1, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 3;
                }
                else if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 11 && band == 3) {
                    t.setFichaEnTablero(posFila, c + 1, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 4;
                }
                else if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 11 && band == 4) {
                    t.setFichaEnTablero(posFila, c - 1, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 5;
                }
                else if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 11 && band == 5) {
                    t.setFichaEnTablero(posFila + 1, c, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 6;
                }
                else if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 11 && band == 6) {
                    t.setFichaEnTablero(posFila - 1, c, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 7;
                    break;
                }
                a++;

            } while (null == null);
            for (int i = f; i <= fFin; i++) {
                for (c = 0; c < 10; c++) {
                    if (t.getCasillaDelTablero(i, c).getFicha().getValor() == -1) {
                        do {
                            z = r.nextInt(40);
                        } while (fichaAuxiliar[z] == null);
                        if (t.getCasillaDelTablero(i, c).getFicha().getValor() == -1) {
                            t.setFichaEnTablero(i, c, fichaAuxiliar[z]);
                            fichaAuxiliar[z] = null;
                        }

                    }
                } // End for

            } // End for

        } // End if
        else if (j == 5) {
        	//coloca en el octavo en direccion al agua
            int a = 0, band = 0, posFila = 0;
            int colAleatoria = r.nextInt(3);
            if (colAleatoria == 0){
                c = 1;
            }else if (colAleatoria == 1){
                c = 5;
            }else if (colAleatoria == 2){
                c = 8;
            }
            posFila = fFin - 1;
          //PARCHAZO!!!!!
            if (posFila == 2) {
            	posFila--;
            }
            do {
                if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 1 && band == 0) {
                    t.setFichaEnTablero(posFila, c, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 1;
                }
                else if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 8 && band == 1) {
                    t.setFichaEnTablero(posFila + 1, c + 1, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 2;
                }
                else if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 9 && band == 2) {
                    t.setFichaEnTablero(posFila - 1, c - 1, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 3;
                }
                else if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 11 && band == 3) {
                    t.setFichaEnTablero(posFila, c + 1, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 4;
                }
                else if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 11 && band == 4) {
                    t.setFichaEnTablero(posFila, c - 1, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 5;
                }
                else if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 11 && band == 5) {
                    t.setFichaEnTablero(posFila + 1, c, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 6;
                }
                else if (fichaAuxiliar[a] != null && fichaAuxiliar[a].getValor() == 11 && band == 6) {
                    t.setFichaEnTablero(posFila - 1, c, fichaAuxiliar[a]);
                    fichaAuxiliar[a] = null;
                    band = 7;
                    break;
                }
                a++;

            } while (null == null);
            for (int i = f; i <= fFin; i++) {
                for (c = 0; c < 10; c++) {
                    if (t.getCasillaDelTablero(i, c).getFicha().getValor() == -1) {
                        do {
                            z = r.nextInt(40);
                        } while (fichaAuxiliar[z] == null);
                        if (t.getCasillaDelTablero(i, c).getFicha().getValor() == -1) {
                            t.setFichaEnTablero(i, c, fichaAuxiliar[z]);
                            fichaAuxiliar[z] = null;
                        }

                    }
                } // End for

            } // End for

        } // End if
        return t;


    } // End Metodo
}
